#
# Package.
#

package iSOCK::Model::Followup;

#
# Parent.
#

use Moose;
use namespace::autoclean;

BEGIN { extends 'iSOCK::Model::Root' }

#
# Dependencies.
#

use File::Slurp qw( slurp );
use JSON qw( decode_json );

#
# Documentation.
#

=head1 NAME

iSOCK::Model::Followup - Catalyst Model

=head1 DESCRIPTION

Catalyst Model.

=head1 AUTHOR

Xavier Caron

=head1 LICENSE

This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

#
# Functions.
#

sub setup_session_directories {
  my ( $self, $option ) = @_;
  
  my $session      = $option->{c}->session;
  my $session_path = $session->{session_path};
  
  mkdir "$session_path/$_", oct 755 for qw( 0_ZIPs_in 1_MIFs_in 2_MIFs_out 3_SPIRITs_out 3_LOGs_out );
  
  $self;
}

sub delete_session_files {
  my ( $self, $option ) = @_;
  
  my $session      = $option->{c}->session;
  my $session_path = $session->{session_path};
  my $product_name = $session->{product_name};
  
  my $count;
  
  no warnings 'uninitialized';
  
  $count += unlink grep { -f } map { glob "$session_path/$product_name$_" } qw( .xls _status.xls _status.html _SPIRITs.tar.bz2 );
  $count += unlink grep { -f } map { glob "$session_path/$_"              } qw( 0_ZIPs_in/*.zip 1_MIFs_in/*.mif 2_MIFs_out/*.mif 3_LOGs_out/*.log 3_SPIRITs_out/*.spirit 5_MIFs_out/*.mif 5_MIFs_out/*.fsl );
  
  $count;
}

sub session_keys {
  qw( mifs_ball spirits_ball big_zip_ball xls_stem xls_file annotated_mifs_ball followup_version svn_component_revision mtw_status ), map { "followup_product_$_" } qw( vendor library name version );
}

sub to_whatever {
  my ( $self, $option ) = @_;
  
  my ( $c, $followup_file, $log ) = ( $option->{c}, $option->{followup_file}, $option->{log} );
  
  my $session      = $c->session;
  my $session_path = $session->{session_path};
  my $parameters   = $c->request->parameters;
  
  my ( $svn_product, $svn_tag ) = map { $session->{$_} } qw( svn_product svn_tag );
  
  no warnings 'uninitialized';

  my $command = "sock_followup_to_whatever --indent 2 --file_indent 0 " .
    ( $followup_file ?
      "--followup $followup_file"
    : "--product $svn_product" . ( $svn_tag ? " --tag $svn_tag" : "" )
    ) .
    
    ( $parameters->{re_include}                  ? " --re_include '"     . $parameters->{re_include}     . "'" : '' ) .
    ( $parameters->{re_exclude}                  ? " --re_exclude '"     . $parameters->{re_exclude}     . "'" : '' ) .

    ( $option->{atp}                             ? ' --atp'                                                    : '' ) .

    ( $option->{svn}                             ? ' --svn'                                                    : '' ) .
    ( $option->{svn_co_from_tags}                ? ' --svn_co_from_tags'                                       : '' ) .
    ( $option->{svn_co_from_trunk}               ? ' --svn_co_from_trunk'                                      : '' ) .

    ( $parameters->{svn_re_include}              ? " --svn_re_include '" . $parameters->{svn_re_include} . "'" : '' ) .
    ( $parameters->{svn_re_exclude}              ? " --svn_re_exclude '" . $parameters->{svn_re_exclude} . "'" : '' ) .

    ( $parameters->{private_registers} eq 'show' ? ' --show_private_registers'                                 : '' ) .
    ( $parameters->{private_registers} eq 'hide' ? ' --hide_private_registers'                                 : '' ) .

    ( $parameters->{do_mifs}                     ? ' --do_mifs'                                                : '' ) . # FIXME && !$parameters->{do_spirits} when SOCK is fixed
    ( $parameters->{do_spirits}                  ? ' --do_spirits'                                             : '' ) .
    ( $parameters->{do_big_zip}                  ? ' --do_big_zip'                                             : '' ) .
    
    ( exists $ENV{ISOCK_PARALLEL}                ? " --parallel $ENV{ISOCK_PARALLEL}"                          : '' )
  ;

  if ( $svn_product ) {
    if ( my $specification_r = $c->model ( 'App::Specification' )->find ( $svn_product ) ) {
      if ( my $repository_r = $specification_r->repository ) {
        $command .= " --repository_url '" . $repository_r->url . "'";

        if ( my $login = $repository_r->login ) {
          $command .= " --repository_login '$login'";
        }
        if ( my $password = $repository_r->password ) {
          $command .= " --repository_password '$password'";
        }
      }
    }
  }

  use warnings;

  if ( $self->spawn ( $c, $command, $log ) ) {
    my   $file   = $followup_file || "$svn_product.xls";
    my ( $stem ) = ( $file =~ /^ (.+) \. xls $/x );

    if ( open my $fh, '<', "$session_path/sock_followup_to_whatever.log" ) {
      while ( <$fh> ) {
        if ( m/ \s+ Product \s+ (vendor|library|name|version) \s+ : \s+ (.+) $/x ) {
          $session->{"followup_product_$1"} = $2 eq 'not found' ? undef : $2;
        }
        elsif ( m/ \s+ Follow-up \s+ version \s+ : \s+ (.+) $/x ) {
          $session->{followup_version}      = $1 eq 'not found' ? undef : $1;
        }
      }
      
      $session->{mifs_ball}    = "${stem}_MIFs.zip"        if $parameters->{do_mifs};
      $session->{spirits_ball} = "${stem}_SPIRITs.tar.bz2" if $parameters->{do_spirits};
      $session->{big_zip_ball} = "${stem}_big.zip"         if $parameters->{do_big_zip};

      $session->{xls_stem}     = $stem;
      $session->{xls_file}     = $file;
    }
    else {
      $log->yell ( "Could not open 'sock_followup_to_whatever.log' LOG file." );
    }
    
    my $json_file = "$session_path/${stem}_status.json";
    
    if ( -f $json_file ) {
      $session->{mtw_status} = decode_json ( slurp ( $json_file ) );
    }
    else {
      $log->yell ( "Could not open '$json_file' JSON file." );
    }
    
    return 1;
  }
  
  $log->yell ( "Problem during invocation." );

  $self->delete_session_keys ({ c => $c });
  
  return;
}

#
# True.
#

1;
